home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cctools / libstuff / execute.c < prev    next >
C/C++ Source or Header  |  1994-03-28  |  3KB  |  107 lines

  1. #include <bsd/libc.h> /* first to get rid of pre-comp warning */
  2. #include <mach/mach.h> /* first to get rid of pre-comp warning */
  3. #include "stdio.h"
  4. #include <signal.h>
  5. #include <sys/wait.h>
  6. #include "stuff/errors.h"
  7. #include "stuff/allocate.h"
  8. #include "stuff/execute.h"
  9.  
  10. /*
  11.  * execute() does an execvp using the argv passed to it.  If the parameter
  12.  * verbose is non-zero the command is printed to stderr.  A non-zero return
  13.  * value indicates success zero indicates failure.
  14.  */
  15. int
  16. execute(
  17. char **argv,
  18. long verbose)
  19. {
  20.     char *name, **p;
  21.     int forkpid, waitpid, termsig;
  22.     union wait waitstatus;
  23.  
  24.     name = argv[0];
  25.  
  26.     if(verbose){
  27.         fprintf(stderr, "+ %s ", name);
  28.         p = &(argv[1]);
  29.         while(*p != (char *)0)
  30.             fprintf(stderr, "%s ", *p++);
  31.         fprintf(stderr, "\n");
  32.     }
  33.  
  34.     forkpid = fork();
  35.     if(forkpid == -1)
  36.         system_fatal("can't fork a new process to execute: %s", name);
  37.  
  38.     if(forkpid == 0){
  39.         if(execvp(name, argv) == -1)
  40.         system_fatal("can't find or exec: %s", name);
  41.         return(1); /* can't get here, removes a warning from the compiler */
  42.     }
  43.     else{
  44.         waitpid = wait(&waitstatus);
  45.         if(waitpid == -1)
  46.         system_fatal("wait on forked process %d failed", forkpid);
  47.         termsig = waitstatus.w_termsig;
  48.         if(termsig != 0 && termsig != SIGINT)
  49.         fatal("fatal error in %s", name);
  50.         return(waitstatus.w_retcode == 0 && termsig == 0);
  51.     }
  52. }
  53.  
  54. /*
  55.  * runlist is used by the routine execute_list() to execute a program and it 
  56.  * contains the command line arguments.  Strings are added to it by
  57.  * add_execute_list().  The routine reset_execute_list() resets it for new use.
  58.  */
  59. static struct {
  60.     int size;
  61.     int next;
  62.     char **strings;
  63. } runlist;
  64.  
  65. /*
  66.  * This routine is passed a string to be added to the list of strings for 
  67.  * command line arguments.
  68.  */
  69. void
  70. add_execute_list(
  71. char *str)
  72. {
  73.     if(runlist.strings == (char **)0){
  74.         runlist.next = 0;
  75.         runlist.size = 128;
  76.         runlist.strings = allocate(runlist.size * sizeof(char **));
  77.     }
  78.     if(runlist.next + 1 >= runlist.size){
  79.         runlist.strings = reallocate(runlist.strings,
  80.                 (runlist.size * 2) * sizeof(char **));
  81.         runlist.size *= 2;
  82.     }
  83.     runlist.strings[runlist.next++] = str;
  84.     runlist.strings[runlist.next] = (char *)0;
  85. }
  86.  
  87. /*
  88.  * This routine reset the list of strings of command line arguments so that
  89.  * an new command line argument list can be built.
  90.  */
  91. void
  92. reset_execute_list(void)
  93. {
  94.     runlist.next = 0;
  95. }
  96.  
  97. /*
  98.  * This routine calls execute() to run the command built up in the runlist
  99.  * strings.
  100.  */
  101. int
  102. execute_list(
  103. long verbose)
  104. {
  105.     return(execute(runlist.strings, verbose));
  106. }
  107.